﻿using System;
using System.Collections.Generic;
using System.Configuration;
using PageViewBusiness.CacheManager;

namespace Redis
{
    public class VoteCache
    {
        private RedisStackClient redisClient;
        private static readonly object synRoot = new object();
        public readonly string REDIS_VOTEKEY = ConfigurationManager.AppSettings["REDIS_VOTEKEY"];
        private readonly string redisHost = ConfigurationManager.AppSettings["REDIS_SERVER"];
        private readonly int MaxItemInQueue = Convert.ToInt32(ConfigurationManager.AppSettings["MaxItemInQueue"]);
        private readonly int MaxItemInQueueToProcess = Convert.ToInt32(ConfigurationManager.AppSettings["MaxItemInQueueToProcess"]);

        private static Queue<string> _keyQueue = new Queue<string>();

        public IMyRedisClient RedisClient
        {
            get
            {
                if (redisClient == null)
                {
                    lock (synRoot)
                    {
                        var arr = redisHost.Split(':');
                        var hostIp = arr[0];
                        var port = int.Parse(arr[1]);
                        var dbNumber = int.Parse(arr[2]);
                        redisClient = new RedisStackClient(hostIp, port, dbNumber);
                    }
                }
                return redisClient;
            }
        }

        //private const ulong DefaultValue = 1;
        //private const ulong Delta = 1;
        // Lock with acsynchrnous for update cache
        private static readonly object _objLock = new object();

        /// <summary>
        /// The enqueue item on list
        /// Author     : ThanhDT
        /// Create Date: 8/29/2012 5:01 PM
        /// </summary>
        /// <param name="item">The item.</param>
        /// <returns></returns>
        public bool Enqueue(string item)
        {
            lock (_objLock)
            {
                // Move enqueue to safe thread
                _keyQueue.Enqueue(item);
                if (_keyQueue.Count >= MaxItemInQueue)
                {
                    Logger.Information("Start queue command.");
                    using (var trans = RedisClient.CreateTransaction())
                    {
                        if (trans == null)
                        {
                            Logger.Information("Create Redis transaction for queue failure.");
                            return false;
                        }

                        int i = 0;
                        while (++i < MaxItemInQueueToProcess && _keyQueue.Count > 0)
                        {
                            var keyFromQueue = _keyQueue.Dequeue();
                            if (keyFromQueue != null)
                            {
                                trans.QueueCommand(t => t.EnqueueItemOnList(REDIS_VOTEKEY, keyFromQueue));
                            }
                            else
                            {
                                Logger.Information("Key got from dotNet Queue is null");
                            }
                        }
                        trans.Commit();
                    }
                    Logger.Information("Committed queue command.");
                }
            }

            return true;
            //var result = RedisClient.EnqueueItemOnList(ListPageViewQueueKey, articleId.ToString());
            //return result;
        }

        /// <summary>
        /// The dequeue item from list
        /// Author     : ThanhDT
        /// Create Date: 8/29/2012 5:01 PM
        /// </summary>
        /// <returns></returns>
        public string DequeueItem()
        {
            lock (_objLock)
            {
                var result = RedisClient.DequeueItemFromList(REDIS_VOTEKEY);
                return result;
            }
        }

        public void SetRedisCache(string key, string data, DateTime dt)
        {
            RedisClient.Add(key, data, dt);
        }
        public string GetRedisCache(string key)
        {
            return RedisClient.Get<string>(key);
        }

    }
}
